'''
Created on Jun 29, 2011

@author: yc30v1m
'''
import logging
from library.AutoLoad import AutoLoad
import os, datetime
from glob import glob
import shutil
log = logging.getLogger(__name__)

class FolderPolling(object):
    '''
    classdocs
    '''
    '''
    polling string
    '''
    _polstr = 'polling'

    '''  
    Folder to perform Polling on
    '''
    _folderLocation = ""
    _backup_folderLocation = ""
    _backup_folder_name = "default_backup"
    '''  
    config file reader 
    '''
    _config = ""
    
    '''  
    flag to identify the Mode of execution
    '''
    _polling_enabled = False
    
    ''' 
    trigger files holder
    '''
    _triggerFiles = ""
    
    # incomming files exists
    incomingFiles = False
    ''' 
    allowed extensions of files
    '''
    _allowed_extensions = ['txt', 'csv']
    _dataFileNames = []
    _dataFilesWithPathInfo = []
    _dataFilesAssoc = {}
    
    def __init__(self):
        self._config = AutoLoad.ClassAsObject('library.Configuration')
        self._setup()
        if self._polling_enabled:
            self.loadFileInfo()
        
       
    def getPollingStatus(self):
        return self._polling_enabled
    
    def isTriggerFileAvailable(self):
        if not self.isTriggerFileEnabled():
            return False
        files = self._getFilesListFromFolder(self._folderLocation)
        if len(files) > 0:
            for file in files:
                if file in self._triggerFiles:
                    return self._triggerFiles
        else:
            return False
    
    def isTriggerFileEnabled(self):
        log.debug("Checking whether Trigger File property is enabled or not")
        return self.retrivePollingConfigOptions('trigger_enable', True)
        
   
    ''' 
    Returns the Incomming Files available in the Incomming folder
    If withFullPath = True is passed we will get the Full absolute path
    '''
    def getIncommingFileNames(self,withFullPath = False):
        if withFullPath:
            if len(self._dataFilesWithPathInfo) > 0:
                return self._dataFilesWithPathInfo
        else:
            if len(self._dataFileNames) > 0:
                return self._dataFileNames
        return False
        
    def getIncommingFileNamesAssoc(self):
        if len(self._dataFilesAssoc) > 0:
            return self._dataFilesAssoc
        log.debug('No Files Found in Incomming Folder')
        return False
    
    def archiveTriggerFile(self):
        if self.isTriggerFileAvailable():
            srcFol = self._folderLocation + os.sep + self.isTriggerFileAvailable()
            os.remove(srcFol)
        return True
    
    def archiveAllFiles(self):
        if len(self._dataFilesWithPathInfo) < 1:
            log.debug('There are no files to archive in source ')
            return False
        if not self._backup_folderLocation:
            return False
        folderName = self._getCurrentTimeForFolderName()
        folderName1 = str(folderName)
        folderName2 = folderName1.replace(':','_')
        currdest = self._backup_folderLocation + os.sep + folderName2
        os.makedirs(currdest)
        for file in self._dataFilesWithPathInfo:
            destFile = self._getFileNameFromFullFilePath(file) 
            if destFile == False:
                continue
            dest = currdest + os.sep + destFile
            self.archiveSingleFile(file, dest)
        return True
    
    def archiveSingleFile(self,src,dest):
        try:
            shutil.move(src,dest)
        except:
            log.critical('unable to move Files to Archive : ' + src )
            AutoLoad.logExceptionInfo()
            return False
        return True     
           
    '''
    @returns the valid file from the location
    we need to make the class singleton
    as to persist the variables of the class '''
    def _getFileNameFromFullFilePath(self, fullFilePath):
        for dataFile in self._dataFileNames:
            if dataFile in fullFilePath:
                return dataFile
            # End If
        # End for
        return False
    
    def loadFileInfo(self):
        try:
            for _extension in self._allowed_extensions:
                pathWithdataFile = glob(self._folderLocation + os.sep + '*.' + _extension)
                dataFiles = self._getFilesListFromFolder(self._folderLocation)
                if len(pathWithdataFile) < 1:
                    log.debug('Unable to find any Incomming Data files at the location : ' + self._folderLocation)
                    continue
                if len(dataFiles) < 1:
                    log.debug('Directory Listing for Incomming Data files was not available : ' + self._folderLocation)
                    continue
                for actualFile in pathWithdataFile:
                    for dataFile in dataFiles:
                        if dataFile in actualFile:
                            self.incomingFiles = True
                            self._dataFileNames.append(dataFile)
                            self._dataFilesWithPathInfo.append(actualFile)
                            self._dataFilesAssoc[dataFile] = actualFile
                            log.debug('Adding the Data File in Elgible Data File List : ' + dataFile)
                            log.debug('Adding the Data File in Elgible Data File List with Full path info : ' + dataFile)
                        #End If
                    #End For dataFile
                #End for ActualFile with Path info
            # End For loop for Extensions
        except:
            log.critical('Exception Occurred reading the Incomming Folder : ')
            AutoLoad.logExceptionInfo()
        
    def _getFilesListFromFolder(self,folder):
        return os.listdir(folder + os.sep)

    def setPollingStatus(self, status=""):
        polConfStr = self._config.getOptionFromSection('testcases', 'mode')
        if polConfStr != False:
            self._polstr = polConfStr
        else:
            log.warn('Test Execution Mode is not setup in Configuration hence processing default configuration')
        if status != "":
            self._polling_enabled = status
        else:
            self._polling_enabled = self.retrivePollingConfigOptions('enabled', True)
        
    '''
    class helper to interact with ConfigParser
    class -- for getting config options of 
    section = testcases_polling  -- default 
    '''
    def retrivePollingConfigOptions(self, option, isBoolOption=False):
        opt = False
        opt = self._config.getOptionFromSection('testcases_' + self._polstr, option, isBoolOption)
        if opt == False:
            log.critical('Unable to retrive the Polling Options : ' + option)
        return opt
    
    '''  
    Setups all the variables of the class with 
    the values from Configuration file
    ''' 
    def _setup(self):
        self.setPollingStatus()
        if self._polling_enabled == True:
            self._folderLocation = self.retrivePollingConfigOptions('incoming_location')
            archive = self.retrivePollingConfigOptions('archive', True)
            if archive == True:
                self._backup_folderLocation = self.retrivePollingConfigOptions('archive_location')
                self.__makeDir(self._backup_folderLocation)
            else:
                self._backup_folderLocation = False
            trg = self.isTriggerFileEnabled()
            if trg == True:
                self._triggerFiles = self.retrivePollingConfigOptions('trigger_filename')
            else:
                self._triggerFiles = False
            self.__makeDir(self._folderLocation)
            
              
    def __makeDir(self,path):
        if not os.path.exists(path):
            try:
                os.makedirs(path)
                print "Makedirectory : " + path
            except:
                AutoLoad.logExceptionInfo()
                return False
        return True
    
    def _getCurrentTimeForFolderName(self):
        if self._backup_folder_name == "default_backup":
            folderName = datetime.datetime.now()
            folderName1 = str(folderName)
            self._backup_folder_name = folderName1.replace(':','_')
        return self._backup_folder_name